package com.sfdk.admin.data.spritesheetEditor
{
	import com.sfdk.admin.ApplicationData;
	import com.sfdk.admin.data.RectangleEx;
	import com.sfdk.data.api.IImageData;
import com.sfdk.data.api.ITreeDataProvider;
import com.sfdk.events.IOEvent;
	import com.sfdk.io.GenericIO;

import flash.display.BitmapData;

import flash.utils.Dictionary;
	
	import mx.collections.ArrayCollection;

	public class AnimatedTilePiece extends GenericIO implements ITreeDataProvider
	{
		public function AnimatedTilePiece(currentDirectory : String = null, filePath : String = null)
		{
			_fullName = filePath;
			if(filePath != null)
			{
				var pathArray : Array = filePath.split("/");
				_type = pathArray[pathArray.length - 2];
				_rootType = pathArray[1];
				_name = pathArray[pathArray.length - 1];
			}
			
			_animationData = new Dictionary();
			_availableTiles = new ArrayCollection();

            super(currentDirectory+filePath, GenericIO.XML_FILE);
		}
		
		private var _fullName:String;
		private var _name:String;
		private var _type:String;
		private var _rootType:String;
		
		public function get fullName():String
		{
			return _fullName;
		}
		
		public function set fullName(value:String):void
		{
			_fullName = value;
		}
		
		public function get label():String
		{
			return _name;
		}
		
		public function set name(value:String):void
		{
			_name = value;
		}
		
		public function get type():String
		{
			return _type;
		}
		
		public function get rootType():String
		{
			return _rootType;
		}

        public function get isImage():Boolean {
            return true;
        }

        public function get imageData():BitmapData {
            return initialImage.imageData;
        }

        private var _initialImage : IImageData;

		public function get initialImage():IImageData
		{
			return _initialImage;
		}
		
		[Bindable]
		public function set initialImage(value:IImageData):void
		{
			_initialImage = value;
		}

		
		private var _availableTiles : ArrayCollection;

		public function get availableTiles(): ArrayCollection
		{
			return _availableTiles;
		}
		
		[Bindable]
		public function set availableTiles(value:ArrayCollection):void
		{
			_availableTiles = value;
		}

		private var _availableFaces : ArrayCollection;

		public function get availableFaces():ArrayCollection
		{
			return _availableFaces;
		}

		[Bindable]
		public function set availableFaces(value:ArrayCollection):void
		{
			_availableFaces = value;
		}

		private var _availableActions : ArrayCollection;

		public function get availableActions():ArrayCollection
		{
			return _availableActions;
		}

		[Bindable]
		public function set availableActions(value:ArrayCollection):void
		{
			_availableActions = value;
		}

		
		private var _animationData : Dictionary;

		public function get animationData():Dictionary
		{
			return _animationData;
		}

		[Bindable]
		public function set animationData(value:Dictionary):void
		{
			_animationData = value;
		}

		public function initAnimationData() : void
		{
			var actionType : String;
			var faceType : String;
			for each(faceType in _availableFaces)
			{
				for each(actionType in _availableActions)
				{
					_animationData[faceType+"_"+actionType] = new ArrayCollection();
				}
			}
		}
		
		public function checkTilePieceConsistency() : void
		{
			var availableTileID : Vector.<int> = new Vector.<int>();
			var availableTileDictionary : Dictionary = new Dictionary();
			var tilePiece : TilePiece;
			for each(tilePiece in _availableTiles)
			{
				availableTileID.push(tilePiece.id);
				availableTileDictionary[tilePiece.id] = tilePiece;
			}
			
			var animationDetailsList : ArrayCollection;
			var animationDetails : AnimationDetails;
			var actionType : String;
			var faceType : String;
			var indexExist : int;
			for each(faceType in _availableFaces)
			{
				for each(actionType in _availableActions)
				{
					animationDetailsList = _animationData[faceType+"_"+actionType];
					for each(animationDetails in animationDetailsList)
					{
						indexExist = availableTileID.indexOf(animationDetails.id);
						if(indexExist == -1)
							animationDetailsList.removeItemAt(animationDetailsList.getItemIndex(animationDetails));
						else
							animationDetails.bitmapData = availableTileDictionary[animationDetails.id].bitmapData;
					}
				}
			}
		}
		
		private var _spritesheet : Spritesheet;
		override protected function init() : void
		{
			var fileXML : XML = _fileInfo;
			var tilesetName : String = fileXML.@tileset;
			_spritesheet = new Spritesheet(ApplicationData.BASE_LOCATION+ApplicationData.SPRITESHEETS_DIRECTORY+ApplicationData.SOURCE_DIRECTORY, tilesetName);
			_spritesheet.addEventListener(IOEvent.LOAD_COMPLETE, onSpritesheetLoadComplete);
		}
		
		private function onSpritesheetLoadComplete(e : IOEvent) : void
		{
			_initialImage = _spritesheet;
			var fileXML : XML = _fileInfo;
			var tiles : XMLList = fileXML.descendants("tile");
			var tile : XML;
			var tilePiece : TilePiece;
			var availableTilesDic : Dictionary = new Dictionary();
			for each(tile in tiles)
			{
				tilePiece = new TilePiece(_spritesheet.imageData);
				tilePiece.init(null, new RectangleEx(tile.@x, tile.@y, tile.@width, tile.@height));
				tilePiece.id = tile.@id;
				tilePiece.regenerateImage(null);
				_availableTiles.addItem(tilePiece);
				availableTilesDic[tilePiece.id] = tilePiece;
			}
			
			var animations : XMLList = fileXML.descendants("animation");
			var animation : XML;
			var tileAnimations : XMLList;
			var tileAnimation : XML;
			var faceType : String;
			var actionType : String;
			var animationData : ArrayCollection;
			var animationDetails : AnimationDetails;
			_availableFaces = new ArrayCollection();
			_availableActions = new ArrayCollection();
			
			for each(animation in animations)
			{
				actionType = animation.@action;
				faceType = animation.@face;
				if(!_availableFaces.contains(faceType))
					_availableFaces.addItem(faceType);
				if(!_availableActions.contains(actionType))
					_availableActions.addItem(actionType);
				animationData = new ArrayCollection();
				tileAnimations = animation.descendants("tileAnimation");
				for each(tileAnimation in tileAnimations)
				{
					animationDetails = new AnimationDetails();
					animationDetails.id = tileAnimation.@id;
					animationDetails.duration = tileAnimation.@duration;
					animationDetails.xOffset = tileAnimation.@xOffset;
					animationDetails.yOffset = tileAnimation.@yOffset;
					
					animationDetails.bitmapData = (availableTilesDic[animationDetails.id] as TilePiece).bitmapData;
					animationDetails.sourceRect = (availableTilesDic[animationDetails.id] as TilePiece).sourceRect;
					animationDetails.reversed = tileAnimation.@reversed == "true";
					animationData.addItem(animationDetails);
				}
				_animationData[faceType+"_"+actionType] = animationData;
			}
            dispatchEvent(new IOEvent(IOEvent.LOAD_COMPLETE));
		}	
		
		
		public function getMaxTileID() : int
		{
			var tilePiece : TilePiece;
			var maxID : int = 0;
			for each(tilePiece in _availableTiles)
			{
				if(tilePiece.id > maxID)
					maxID = tilePiece.id;
			}
			return maxID;
		}
	}
	
	
}